package com.yantong.service.impl;

import com.alibaba.fastjson.JSON;
import com.yantong.config.LocalRedis;
import com.yantong.constant.BusinessCode;
import com.yantong.exception.BDException;
import com.yantong.pojo.*;
import com.yantong.mapper.ProductCentreMapper;
import com.yantong.service.ProductCentreService;
import com.yantong.pojo.vo.MemberCartVo;
import com.yantong.mapper.MemberCartMapper;
import com.yantong.service.MemberCartService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.yantong.constant.CacheKeyLocal.CACHE_KEY_PRODUCT_CENTRE_SKU_SALE;


/**
 * @author kanghaixin
 * @date 2018/9/11.20:07
 */
@Service
public class MemberCartServiceImpl implements MemberCartService {
    @Autowired
    private MemberCartMapper memberCartMapper;

    @Autowired
    @Lazy
    private ProductCentreService productCentreService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private ProductCentreMapper productCentreMapper;
    @Autowired
    private LocalRedis localRedis;

    @Override
    public int saveItem(MemberCart item) {
        if (item == null || (item.getProductId() == null && item.getTotal() < 0)) {
            return 0;
        }
        MemberCartExample example = new MemberCartExample();
        MemberCartExample.Criteria criteria = example.createCriteria();
        criteria.andProductIdEqualTo(item.getProductId())
                .andDeletedEqualTo(0)
                .andIsorderEqualTo(0)
                .andMidEqualTo(item.getMid());
        if (item.getSkuId() != null) {
            criteria.andSkuIdEqualTo(item.getSkuId());
        }
        if (null != item.getCentreId()) {
            example.setCentreId(item.getCentreId());
        }

        List<MemberCart> list = memberCartMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(list)) {
            MemberCart record = list.get(0);
            if (record.getTotal() + item.getTotal() <= 0) {
                this.removeItem(record.getId());
            }
            record.setTotal(record.getTotal() + item.getTotal());
            return memberCartMapper.updateByPrimaryKeySelective(record);
        }
        return memberCartMapper.insertSelective(item);
    }

    @Override
    public int  saveRedis(MemberCart item) {
        if (item == null || (item.getProductId() == null && item.getTotal() < 0)) {
            return 0;
        }
        ProductCentre productCentre = productCentreService.getByKeyWithCache(item.getProductId());
        if (productCentre == null) {
            return 0;
        }

        if (productCentre.getHasoption() != null && productCentre.getHasoption() == 1) {
            ProductSkuCentre skuCentre = productCentreService.getSkuBySpecs(item.getSpecs());
            if( skuCentre == null ){
                throw new BDException(BusinessCode.ORDER_PRODUCT_SKU_ERROR);
            }
//            long sSale = localRedis.increamNum(CacheKeyLocal.CACHE_KEY_PRODUCT_CENTRE_SKU_SALE.concat(String.valueOf(sku.getId())), item.getTotal());
            long sSale = localRedis.increamNum(CACHE_KEY_PRODUCT_CENTRE_SKU_SALE.concat(String.valueOf(skuCentre.getSkuId())), item.getTotal());
            if (skuCentre.getStock() < sSale) {
                throw new BDException(productCentre.getTitle().concat("已卖完,请删除该商品"));
            }
        }

        //判断是否有商品,如果有做修改操作
        Object str = null;
//        if (productCentre.getIsKuaidi()==0){
        str = redisTemplate.opsForHash().get("card:" + item.getMid() + ":" + item.getCentreId(), item.getProductId() + ":" + item.getSpecs());
//        }else {
//            str=redisTemplate.opsForHash().get("card:"+item.getMid()+":",item.getProductId()+":"+item.getSkuId());
//        }

        String s = redisTemplate.opsForValue().get("cardTotal:" + item.getMid() + ":" + item.getProductId());
        MemberCartVo memberCartVo;
        if (str == null) {
            memberCartVo = new MemberCartVo();
            if (item.getTotal() <= 0) {
                return 0;
            }
            memberCartVo.setTotal(item.getTotal());
            memberCartVo.setId(item.getProductId() + ":" + item.getSpecs());
        } else {
            memberCartVo = JSON.parseObject(str.toString(), MemberCartVo.class);
            if (item.getTotal() + memberCartVo.getTotal() <= 0) {
                removeItemRedis(item.getMid(), item.getCentreId(), memberCartVo.getId(), productCentre.getIsKuaidi());
                return 1;
            }
            memberCartVo.setTotal(item.getTotal() + memberCartVo.getTotal());
        }
        //商品数量
        if (s == null) {
            redisTemplate.opsForValue().set("cardTotal:" + item.getMid() + ":" + item.getProductId(), memberCartVo.getTotal() + "");
        } else {
            Integer total = Integer.valueOf(s) + item.getTotal();
            redisTemplate.opsForValue().set("cardTotal:" + item.getMid() + ":" + item.getProductId(), total + "");
        }

        //规格项
        Long skuId = null;
        if (StringUtils.isNotEmpty(item.getSpecs())) {
            ProductSkuCentre productSkuCentre = productCentreService.getSkuBySpecs(item.getSpecs());
            if (productSkuCentre != null) {
                skuId = productSkuCentre.getId();
            } else {
                throw new BDException(productCentre.getTitle() + "-规格选择有误，请重试！");
            }
            memberCartVo.setSkuId(skuId);
            memberCartVo.setSkuTitle(productSkuCentre.getTitle());
            memberCartVo.setSpecs(item.getSpecs());
            memberCartVo.setMarketprice(productSkuCentre.getMarketprice());
        } else {
            memberCartVo.setSkuId(item.getSkuId());
            memberCartVo.setSkuTitle(item.getSkuTitle());
            memberCartVo.setMarketprice(item.getMarketprice());
        }

        memberCartVo.setMid(item.getMid());
        memberCartVo.setProductId(item.getProductId());
        memberCartVo.setSpecTitle(productCentre.getSpecTitle());
        memberCartVo.setProdlabels(productCentre.getProdlabels());

        memberCartVo.setIsKuaidi(productCentre.getIsKuaidi());
        String pic = StringUtils.isBlank(productCentre.getThumbSquare()) == true ? productCentre.getThumb() : productCentre.getThumbSquare();
        memberCartVo.setThumbSquare(pic);
        memberCartVo.setUnit(productCentre.getUnit());
        memberCartVo.setTitle(productCentre.getTitle());
        memberCartVo.setTeamid(item.getTeamid());
        memberCartVo.setCentreId(item.getCentreId());
        memberCartVo.setConsumptionIntegral(item.getConsumptionIntegral());
        //商品购物车

//        if (productCentre.getIsKuaidi()==0){
        redisTemplate.opsForHash().put("CART_KEY:" + item.getProductId(), item.getMid() + ":" + item.getCentreId() + "," + item.getProductId() + ":" + item.getSpecs(), item.getMid() + ":" + item.getCentreId());

        redisTemplate.opsForHash().put("card:" + item.getMid() + ":" + item.getCentreId(), item.getProductId() + ":" + item.getSpecs(), JSON.toJSONString(memberCartVo));

//        }else {
//            redisTemplate.opsForHash().put("CART_KEY:"+item.getProductId(),item.getMid()+":"+","+item.getProductId()+":"+item.getSkuId(),item.getMid()+":");
//            redisTemplate.opsForHash().put("card:"+item.getMid()+":",item.getProductId()+":"+item.getSkuId(),JSON.toJSONString(memberCartVo));
//
//        }
        return 1;
    }

    @Override
    public int removeItem(Long itemId) {
        MemberCart item = new MemberCart();
        item.setId(itemId);
        item.setDeleted(1);
        item.setUpdateTime(new Date());
        return memberCartMapper.updateByPrimaryKeySelective(item);
    }

    @Override
    public void removeItemRedis(Long memberId, Long centreId, String itemId, Integer isKuaidi) {
        String[] split = itemId.split(":");
        //判断是否存在sku,如果不存在sku直接全部删除,存在修改商品数量,删除购物车
        if ("null".equals(split[1])) {
            redisTemplate.delete("cardTotal:" + memberId + ":" + split[0]);
        } else {
            Object object = null;
//            if (isKuaidi==0){
            object = redisTemplate.opsForHash().get("card:" + memberId + ":" + centreId, itemId);
//            }else {
//                object = redisTemplate.opsForHash().get("card:"+memberId + ":" , itemId);
//            }

            String s = redisTemplate.opsForValue().get("cardTotal:" + memberId + ":" + split[0]);
            if (object != null && StringUtils.isNotBlank(s)) {
                MemberCartVo memberCartVo = JSON.parseObject(object.toString(), MemberCartVo.class);
                memberCartVo.getTotal();
                Integer total = Integer.valueOf(s) - memberCartVo.getTotal();
                if (total <= 0) {
                    redisTemplate.delete("cardTotal:" + memberId + ":" + split[0]);
                } else {
                    redisTemplate.opsForValue().set("cardTotal:" + memberId + ":" + split[0], total + "");

                }
            }

        }
//        if (isKuaidi==0){
        redisTemplate.opsForHash().delete("card:" + memberId + ":" + centreId, itemId);
//        }else {
//            redisTemplate.opsForHash().delete("card:"+memberId+":",itemId);
//        }


    }

    @Override
    public int editCart(MemberCart item) {
        if (item == null) {
            return 0;
        }
        return memberCartMapper.updateByPrimaryKeySelective(item);
    }

    @Override
    public int editCartRedis(MemberCartVo item) {
        if (item == null) {
            return 0;
        }
        Object str;
//        if (item.getIsKuaidi()==0){
        str = redisTemplate.opsForHash().get("card:" + item.getMid() + ":" + item.getCentreId(), item.getId());
//        }else {
//            str=redisTemplate.opsForHash().get("card:"+item.getMid()+":",item.getId());
//        }

        String[] split = item.getId().split(":");
        String s = redisTemplate.opsForValue().get("cardTotal:" + item.getMid() + ":" + split[0]);
        if (str == null || s == null) {
            return 0;
        }
        MemberCartVo memberCartVo = JSON.parseObject(str.toString(), MemberCartVo.class);
        Integer newTotal = item.getTotal() - memberCartVo.getTotal();
        if (item.getTotal() <= 0) {
            return 0;
        }
        memberCartVo.setTotal(item.getTotal());
        //判断是否存在sku,存在则原有数量减此次数量,更新商品数量,更新购物车数量
        if ("null".equals(split[1])) {
            redisTemplate.opsForValue().set("cardTotal:" + item.getMid() + ":" + split[0], item.getTotal() + "");
        } else {
            Integer total = Integer.valueOf(s) + newTotal;
            redisTemplate.opsForValue().set("cardTotal:" + item.getMid() + ":" + split[0], total + "");
        }
//        if (item.getIsKuaidi()==0){
        redisTemplate.opsForHash().put("card:" + item.getMid() + ":" + item.getCentreId(), item.getId(), JSON.toJSONString(memberCartVo));
//        }else {
//            redisTemplate.opsForHash().put("card:"+item.getMid()+":",item.getId(),JSON.toJSONString(memberCartVo));
//        }

        return 1;
    }

    @Override
    public PageDO<MemberCart> listCartItems(Long mid, int offset, int limit) {
        PageDO<MemberCart> pageDO = new PageDO<>();
        pageDO.setOffset(offset);
        pageDO.setLimit(limit);

        Map<String, Object> params = new HashMap<>(2);
        params.put("mid", mid);
        int total = memberCartMapper.countByParams(params);
        if (total > 0) {
            List<MemberCart> listByParams = memberCartMapper.listByParams(params, new RowBounds(offset, limit));
            pageDO.setRows(listByParams);
        }
        return pageDO;
    }

    @Override
    public int countTotal(Map<String, Object> params) {

        return memberCartMapper.countTotal(params);
    }

    @Override
    public int countTotalRedis(Long memberId, Long centreId) {
        List<Object> values = redisTemplate.opsForHash().values("card:" + memberId + ":" + centreId);
        List<Object> values1 = redisTemplate.opsForHash().values("card:" + memberId + ":");
        if (CollectionUtils.isNotEmpty(values1)) {
            values.addAll(values1);
        }
        int count = 0;
        if (CollectionUtils.isNotEmpty(values)) {
            for (Object value : values) {
                MemberCartVo memberCartVo = JSON.parseObject(value.toString(), MemberCartVo.class);
                count += memberCartVo.getTotal();
            }
        }
        return count;
    }

    @Override
    public PageDO<MemberCartVo> listMemberCar(Long memberId, Long centreId, Integer offset, Integer limit) {
        PageDO<MemberCartVo> pageDO = new PageDO<>();
        pageDO.setOffset(offset);
        pageDO.setLimit(limit);

        Map<String, Object> params = new HashMap<>(2);
        params.put("mid", memberId);
        params.put("centreId", centreId);
        int total = memberCartMapper.countByParams(params);
        if (total > 0) {
            List<MemberCartVo> listByParams = memberCartMapper.listByParams1(params, new RowBounds(offset, limit));
            pageDO.setRows(listByParams);
        }
        return pageDO;
    }

    @Override
    public PageDO<MemberCartVo> listMemberCarRedis(Long memberId, Long centreId, Integer offset, Integer limit) {
        return listMemberCarRedis(memberId, centreId, null, offset, limit);
    }

    @Override
    public PageDO<MemberCartVo> listMemberCarRedis(Long memberId, Long centreId, Long productId, Integer offset, Integer limit) {
        PageDO<MemberCartVo> pageDO = new PageDO<>();
        pageDO.setOffset(offset);
        pageDO.setLimit(limit);
        List<Object> values = redisTemplate.opsForHash().values("card:" + memberId + ":" + centreId);
        List<Object> values1 = redisTemplate.opsForHash().values("card:" + memberId + ":");
        if (CollectionUtils.isNotEmpty(values1)) {
            values.addAll(values1);
        }

        List<MemberCartVo> memberCartVos = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(values)) {
            for (Object value : values) {
                MemberCartVo memberCartVo = JSON.parseObject(value.toString(), MemberCartVo.class);
                //查询商品是否下架
                ProductCentre pc = productCentreMapper.getProductByIdAndTime(memberCartVo.getProductId());
                //如果加了商品ID过滤，则需要增加这个判断
                if(null != productId && pc.getId().longValue() != productId.longValue()){
                    continue;
                }
                //商品没下架
                if (pc != null) {
                    //添加
                    memberCartVos.add(memberCartVo);
                } else {
                    String skuid = memberCartVo.getSkuId() == null ? "null" : memberCartVo.getSkuId() + "";
                    //下架删除购物车
                    removeItemRedis(memberId, centreId, memberCartVo.getProductId() + ":" + skuid, memberCartVo.getIsKuaidi());
                }
            }
            pageDO.setRows(memberCartVos);
        }
        return pageDO;
    }


    /**
     * 得到购物车中所有下架的商品(无用)
     *
     * @return
     */
    public List<MemberCartVo> getMemCarList() {
        return memberCartMapper.getMemCarList();
    }

    ;


    /**
     * 批量删除购物车
     *
     * @param ids
     * @return
     */
    public int removeMemCar(List<MemberCartVo> ids) {
        return memberCartMapper.removeMemCar(ids);
    }


}
